﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Mvc.Html;
using Microsoft.Practices.Unity;
using Vit.Web.Extensions;
using Vit.Web.Data;
using Vit.Web.Services;

namespace Vit.Web.Mvc
{
    public class HtmlDefaultTemplateProvider
    {
        public static string GetControl(DataViewType viewType, string dataTypeName, string fieldName, string format, object val, string htmlAttributes, string htmlStyles)
        {
            switch (viewType)
            {
                case DataViewType.List:
                case DataViewType.Detail:
                    return GetLabel(dataTypeName, format, val, htmlAttributes, htmlStyles);
                case DataViewType.New:
                case DataViewType.Edit:
                case DataViewType.Search:
                    return GetEditor(dataTypeName, fieldName, format, val, htmlAttributes, htmlStyles);
            }
            return string.Empty;
        }

        private static string GetLabel(string dataTypeName, string format, object val, string htmlAttributes, string htmlStyles)
        {
            string txt = GetFormatValue(format, val);
            string style = "";
            if (!string.IsNullOrEmpty(htmlStyles))
                style = string.Format(" style='{0}'", htmlStyles);

            switch (dataTypeName.ToLower())
            {
                case "string":
                case "guid":
                default:
                    return string.Format("<span {1}{2}>{0}</span>",
                        txt, htmlAttributes, style);
                case "datetime":
                    if (string.IsNullOrEmpty(format))
                        txt = string.Format("{0:yyyy-MM-dd}", val);
                    return string.Format("<span {1}{2}>{0}</span>",
                        txt, htmlAttributes, style);
            }
        }

        private static string GetEditor(string dataTypeName, string fieldName, string format, object val, string htmlAttributes, string htmlStyles)
        {
            string txt = GetFormatValue(format, val);
            string style = "";
            if (!string.IsNullOrEmpty(htmlStyles))
                style = string.Format(" style='{0}'", htmlStyles);

            switch (dataTypeName.ToLower())
            {
                case "string":
                case "guid":
                default:
                    return string.Format("<input type='text' id='{0}' name='{0}' value='{1}' {2}{3}/>",
                        fieldName, txt, htmlAttributes, style);
                case "datetime":
                    if (string.IsNullOrEmpty(format))
                        txt = string.Format("{0:yyyy-MM-dd}", val);
                    return string.Format("<input type='text' id='{0}' name='{0}' value='{1}' calss='datepicker' {2}{3}/>",
                         fieldName, txt, htmlAttributes, style);
            }
        }

        public static string GetReferenceDisplayText(Type entityType, string format, object val, string htmlAttributes, string htmlStyles)
        {
            string style = "";
            if (!string.IsNullOrEmpty(htmlStyles))
                style = string.Format(" style='{0}'", htmlStyles);

            string source = DataSourceService.GetDisplayText(entityType, val);

            if (!string.IsNullOrEmpty(format))
                source = string.Format(format, source);

            return string.Format("<span {1}{2}>{0}</span>", source, htmlAttributes, style);
        }

        public static string GetReferenceDropdownList(Type entityType, string fieldName, object val, string datasourceName, object args, string optionLabel, string htmlAttributes, string htmlStyles)
        {
            string style = "";
            if (!string.IsNullOrEmpty(htmlStyles))
                style = string.Format(" style='{0}'", htmlStyles);

            StringBuilder sb = new StringBuilder();
            IEnumerable<SelectListItem> listItems = DataSourceService.GetSourceListItems(entityType, datasourceName, args);
            sb.AppendFormat("<select id=\"{0}\" name=\"{0}\" {1}{2}>", fieldName, htmlAttributes, style);

            if (!string.IsNullOrEmpty(optionLabel))
                sb.AppendFormat("<option value=\"\">{0}</option>", optionLabel);

            foreach (var item in listItems)
            {
                bool selected = (val == null ? false : val.ToString() == item.Value);
                sb.AppendFormat("<option value=\"{0}\"{2}>{1}</option>", item.Value, item.Text,
                    selected ? " selected=\"true\"" : "");
            }

            sb.Append("</selected>");

            return sb.ToString();
        }

        public static string GetReferenceDialog(Type entityType, string fieldName, string format, object val, string controller, string buttonText, string dialogTitle, string htmlAttributes, string htmlStyles)
        {
            string style = "";
            if (!string.IsNullOrEmpty(htmlStyles))
                style = string.Format(" style='{0}'", htmlStyles);
            
            string source = DataSourceService.GetDisplayText(entityType, val);

            if (!string.IsNullOrEmpty(format))
                source = string.Format(format, source);

            if(string.IsNullOrEmpty(buttonText))
                buttonText = "...";

            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("<input type='text' id='{0}_Text' name='{0}_Text' value='{1}' readonly='true' {2}{3}/>",
                fieldName, source, htmlAttributes, style);
            sb.AppendFormat("<input type='hidden' id='{0}' name='{0}' value='{1}' />",
                fieldName, val);
            sb.AppendFormat("<a href='/{0}/Dialog/0/{1}/{2}' class='thickbox' title='{4}'>{3}</a>",
                controller, fieldName, val, buttonText, dialogTitle);

            return sb.ToString();
        }

        private static string GetFormatValue(string format, object val)
        {
            string txt = string.Empty;
            if (val != null)
            {
                if (!string.IsNullOrEmpty(format))
                    txt = string.Format(format, val);
                else
                    txt = val.ToString();
            }

            return txt;
        }

        private static IDataSourceService DataSourceService
        {
            get
            {
                IUnityContainer unity = VitApplication.Current.UnityContainer;
                return unity.Resolve<IDataSourceService>();
            }
        }
    }
}
